package com.aji.controller;

import com.aji.dto.ElementDto;
import com.aji.dto.IsotopeDto;
import com.aji.entity.Ores1;
import com.aji.entity.Ores2;
import com.aji.entity.Ores3;
import com.aji.result.Result;
import com.aji.service.ElementService;
import com.aji.service.IsotopeService;
import com.aji.service.LocService;
import com.aji.vo.CreatedElement;
import com.aji.vo.ElementVo;
import com.aji.vo.NumberOres;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@RequestMapping("/view")
@Api(tags = "可视化图")
@RequiredArgsConstructor
public class ViewController {
    final LocService locService;
    final ElementService elementService;
    final IsotopeService isotopeService;
    @ApiOperation("获取一级矿区列表")
    @GetMapping("/listOres1")
    public Result listOres1(){
        List<Ores1>ores1List = locService.selectOres1();
        return Result.success(ores1List);
    }
    @ApiOperation("获取二级矿区列表")
    @GetMapping("/listOres2")
    public Result listOres2(){
        List<Ores2>ores2List = locService.selectOres2ByOres1(null);
        return Result.success(ores2List);
    }

    @ApiOperation("获取三级矿区列表")
    @GetMapping("/listOres3")
    public Result listOres3(){
        List<Ores3>ores3List = locService.selectOres3ByOres2(null,null);
        return Result.success(ores3List);
    }
    @ApiOperation("获取Element创建记录")
    @GetMapping("/listCreatedElement")
    public Result listCreatedElement(){
        List<ElementVo> elementVoList = elementService.selectCon(null);
        List<CreatedElement>createdElementList=
                elementVoList.stream()
                        .map(n->CreatedElement.builder().contents(n.getContents()).typeName(n.getTypeName()).createTime(n.getCreateTime()).build())
                        .collect(Collectors.toList());
        return Result.success(createdElementList);
    }
    @ApiOperation("获取一级矿区样本数量")
    @GetMapping("/numberOres1")
    public Result numberOres1(){
        List<NumberOres> numberOresList = numberOresAbstract(locService::selectOres1, Ores1.class);
        return Result.success(numberOresList);
    }
    @ApiOperation("获取二级矿区样本数量")
    @GetMapping("/numberOres2")
    public Result numberOres2(){
        List<NumberOres> numberOresList = numberOresAbstract(locService::selectOres2, Ores2.class);
        return Result.success(numberOresList);
    }
    @ApiOperation("获取三级矿区样本数量")
    @GetMapping("/numberOres3")
    public Result numberOres3(){
        List<NumberOres> numberOresList = numberOresAbstract(locService::selectOres3, Ores3.class);
        return Result.success(numberOresList);
    }

    private List<NumberOres> numberOresAbstract(Supplier<List<?>> oresSupplier, Class<?> oresClass){
        List<?> oresList = oresSupplier.get();
        return oresList.stream().
                map(n->{
                    //反射获取类名
                    String simpleName = oresClass.getSimpleName();
                    //反射获得OresName，Id
                    try {
                        //Name,Id
                        String oresName = (String)oresClass.getMethod("get" + simpleName + "Name").invoke(n);
                        Integer oresId = (Integer)oresClass.getMethod("get" + simpleName + "Id").invoke(n);
                        //Dto反射获取
                        ElementDto elementDto = ElementDto.builder().build();
                        IsotopeDto isotopeDto = IsotopeDto.builder().build();
                        ElementDto.class.getMethod("set" + simpleName + "Id", Integer.class).invoke(elementDto,oresId);
                        IsotopeDto.class.getMethod("set" + simpleName + "Id", Integer.class).invoke(isotopeDto,oresId);
                        return  NumberOres.builder().oresName(oresName).
                                elementNumber((long) elementService.selectCon(elementDto).size())
                                .isotopeNumber((long) isotopeService.selectCon(isotopeDto).size()).build();

                    } catch (NoSuchMethodException e) {
                        throw new RuntimeException(e);
                    } catch (InvocationTargetException e) {
                        throw new RuntimeException(e);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                        }
                )
                .collect(Collectors.toList());
    }
}
